from distutils.util import strtobool
from sqlalchemy.orm import Session
from app.monitor_metrics.models.prom_network_group import PromNetworkGroup
from app.monitor_metrics.models.prom_network_probe import PromNetworkProbe

from common.welab_k8s.k8s_blackbox_probe import K8sBlackBoxProbe

from core.response import resp_400, resp_500, HTTPExceptionCustom
from core.logger import logger


class PromNetworkProbeHandler():
    """  network probe Handler
    """
    def __init__(self):
        self.k8s_blackbox_probe = K8sBlackBoxProbe()


    def get_network_probe_search(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        根据表字段模糊匹配，获取网络探测任务
        """
        try:
            field_info = {field: value}
            order_info = {"name": "asc"}
            result = PromNetworkProbe.filter_by_field_search(db, page, per_page, field_info, order_info)
            if not result:
                logger.error(f"get network probe, result is null => {field}:{value}")
                return False, None

            # 过滤内部标签
            for item in result["items"]:
                item["labels"] = {
                    key: value
                    for key, value in item["labels"].items()
                    if not key.startswith("i_")
                }

        except Exception as e:
            message = f"get network probe by {field}:{value} error "
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result



    def get_network_probe_match(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        根据表字段完全匹配，获取网络探测任务
        """
        try:
            result = PromNetworkProbe.filter_by_field_match(db, page, per_page, {field: value})
            if not result:
                logger.error(f"get network probe match, result is null => {field}:{value}")
                return False, None

            # 过滤内部标签
            for item in result["items"]:
                item["labels"] = {
                    key: value
                    for key, value in item["labels"].items()
                    if not key.startswith("i_")
                }
        except Exception as e:
            message = f"get network probe match by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result




    def add_network_probe_to_database(self, db: Session, data):
        """
        增加一个网络探测任务的信息到数据库
        """
        try:
            network_probe = PromNetworkProbe.get_object_by_name(db, data["name"])
            if network_probe:
                # 如果存在， 则异常返回
                logger.error(f"add network probe failed, {data['name']} was exist")
                return False

            network_group_object = PromNetworkGroup.get_object_by_uuid(db, data["network_group_uuid"])
            if not network_group_object:
                # 如果指定网络探测组不存在，则异常返回
                logger.error(f"add network probe failed, network_group:{data['network_group_uuid']} not exist")
                return False

            # 添加数据库
            network_group_info = PromNetworkGroup.get_object_info_by_uuid(db, data["network_group_uuid"])
            data["labels"]["i_department"] = network_group_info["department"]
            data["labels"]["i_network_group"] = network_group_info["name"]
            data["labels"]["i_network_probe"] = data["name"]

            result = PromNetworkProbe.add(db, data)
            if not result:
                logger.error(f"add network probe to database failed")
                return False
        except Exception as e:
            message = f"add network probe to database error"
            logger.exception(f"{message} => {e}")
            return False

        return True




    def add_network_probe(self, db: Session, data):
        """
        增加一个网络探测任务
        """
        try:
            # 添加信息到数据库
            result = self.add_network_probe_to_database(db, data)
            if not result:
                logger.error(f"add network probe to database failed")
                return False

            # 在prometheus中创建一个探测任务
            result = self.k8s_blackbox_probe.add_blackbox_probe(data)
            if not result:
                # 清理数据库中的数据
                self.delete_network_probe(db, data)

                logger.error(f"add network probe to prometheus failed")
                return False

        except Exception as e:
            message = f"add network probe to database error"
            logger.exception(f"{message} => {e}")
            return False

        logger.info(f"add network probe to database success")
        return True



    def update_network_probe_to_prometheus(self, db: Session, data: dict):
        """
        更新prometheus里面的数据
        """
        network_probe_info = PromNetworkProbe.get_object_info_by_uuid(db, data["uuid"])
        if "network_group_uuid" not in data:
            data["network_group_uuid"] = network_probe_info["network_group_uuid"]
        network_group_info = PromNetworkGroup.get_object_info_by_uuid(db, data["network_group_uuid"])

        # 添加其他数据
        data["name"] = network_probe_info["name"]
        data["module"] = network_probe_info["module"]
        data["labels"]["i_department"] = network_group_info["department"]
        data["labels"]["i_network_group"] = network_group_info["name"]
        data["labels"]["i_network_probe"] = data["name"]

        if strtobool(str(data["state"])):
            if self.k8s_blackbox_probe.is_exist(data['name']):
                # 存在则更新
                result = self.k8s_blackbox_probe.update_blackbox_probe(data)
            else:
                # 不存在则新建
                result = self.k8s_blackbox_probe.add_blackbox_probe(data)
        else:
            # 删除
            result = self.k8s_blackbox_probe.delete_blackbox_probe(data["name"])

        if not result:
            logger.error(f"update network probe from prometheus failed {data['name']}")
            return False

        return True



    def update_network_probe(self, db: Session, data: dict):
        """
        修改网络探测任务
        """
        try:
            network_probe = PromNetworkProbe.get_object_by_uuid(db, data["uuid"])
            if not network_probe:
                # 如果不存在， 则异常返回
                logger.error(f"update network probe failed, uuid:{data['uuid']} not exist")
                return False

            # 更新prometheus的数据
            result = self.update_network_probe_to_prometheus(db, data)
            if not result:
                logger.error(f"update network probe to prometheus failed")
                return False

            # 更新数据库的网络探测任务
            result = PromNetworkProbe.update(db, data)
            if not result:
                logger.error(f"update network probe to database failed")
                return False
        except Exception as e:
            message = f"update network probe error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True




    def delete_network_probe(self, db: Session, data: dict):
        """
        删除网络探测任务
        """
        try:
            network_probe = PromNetworkProbe.get_object_by_uuid(db, data['uuid'])
            if not network_probe:
                # 如果不存在， 则异常返回
                logger.error(f"delete network probe failed, uuid:{data['uuid']} not exist")
                return False

            # 从prometheus中删除
            result = self.k8s_blackbox_probe.delete_blackbox_probe(network_probe.name)
            if not result:
                logger.error(f"delete network probe from prometheus failed {network_probe.name}")
                return False

            # 从数据库中删除
            PromNetworkProbe.delete_object_by_uuid(db, data['uuid'])
        except Exception as e:
            message = f"delete network probe uuid:{data['uuid']} error => {e}"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True

